home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-06-30 | 10.8 KB | 399 lines |
- /*
- * @(#)TableView.java 1.7 98/04/09
- *
- * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
- package com.sun.java.swing.text;
-
- import java.awt.*;
-
- /**
- * <p>
- * Implements View interface for a table, that is composed of a
- * specific element structure where the child elements of the element
- * this view is responsible for represent rows and the child
- * elements of the row elements are cells. The cell elements can
- * have an arbitrary element structure under them.
- * <pre><code>
- * TABLE
- * ROW
- * CELL
- * CELL
- * ROW
- * CELL
- * CELL
- * </code></pre>
- * <p>
- * This is implemented as a hierarchy of boxes, the table itself
- * is a vertical box, the rows are horizontal boxes, and the cells
- * are vertical boxes. The cells are allowed to span multiple
- * columns and rows. By default, the table can be thought of as
- * being formed over a grid, where cells can request to span more
- * than one grid cell. The default horizontal span of table cells
- * will be based upon this grid, but can be changed by reimplementing
- * the requested span of the cell.
- *
- * @author Timothy Prinzing
- * @version 1.7 04/09/98
- * @see View
- */
- public class TableView extends BoxView {
-
- /**
- * Constructs a TableView for the given element.
- *
- * @param elem the element that this view is responsible for
- */
- public TableView(Element elem) {
- super(elem, View.Y_AXIS);
- }
-
- /**
- * Creates a new table row.
- *
- * @param elem an element
- * @return the row
- */
- protected TableRow createTableRow(Element elem) {
- return new TableRow(elem);
- }
-
- /**
- * Creates a new table cell.
- *
- * @param elem an element
- * @return the cell
- */
- protected TableCell createTableCell(Element elem) {
- return new TableCell(elem);
- }
-
- /**
- * Fetches the span (width) of the given column.
- * This is used by the nested cells to query the
- * sizes of grid locations outside of themselves.
- */
- int getColumnSpan(int col) {
- return colWidths[col];
- }
-
- /**
- * Fetches the span (height) of the given row.
- * This is used by the nested cells to query the
- * sizes of grid locations outside of themselves.
- */
- int getRowSpan(int row) {
- View v = getView(row);
- return (int) v.getPreferredSpan(Y_AXIS);
- }
-
- /**
- * Loads all of the children to initialize the view.
- * This is called by the <code>setParent</code> method.
- * This is reimplemented to build rows using the
- * <code>createTableRow</code> method and then
- * proxy cell entries for each of the cells that
- * span multiple columns or rows, substantially
- * reducing the complexity of the layout calculations.
- *
- * @param f the view factory
- */
- protected void loadChildren(ViewFactory f) {
- Element e = getElement();
- int n = e.getElementCount();
- if (n > 0) {
- View[] added = new View[n];
- for (int i = 0; i < n; i++) {
- added[i] = createTableRow(e.getElement(i));
- }
- replace(0, 0, added);
- }
-
- // fill in the proxy cells
- for (int row = 0; row < n; row++) {
- View rv = getView(row);
- for (int col = 0; col < rv.getViewCount(); col++) {
- View cv = rv.getView(col);
- if (cv instanceof TableCell) {
- TableCell cell = (TableCell) cv;
- if ((cell.getColumnCount() > 1) ||
- (cell.getRowCount() > 1)) {
-
- // fill in the proxy entries for this cell
- for (int i = row; i < row + cell.getRowCount(); row++) {
- for (int j = col; j < col + cell.getColumnCount(); j++) {
- if (i != 0 && j != 0) {
- addProxy(i, j, cell);
- }
- }
- }
- }
- }
- }
- }
-
- calculateGrid();
- }
-
- void calculateGrid() {
- int ncols = 0;
- int nrows = getViewCount();
- for (int i = 0; i < nrows; i++) {
- View row = getView(i);
- ncols = Math.max(ncols, row.getViewCount());
- }
-
- colWidths = new int[ncols];
- for (int i = 0; i < nrows; i++) {
- View row = getView(i);
- ncols = row.getViewCount();
- for (int j = 0; j < ncols; j++) {
- TableCell cell = (TableCell) row.getView(j);
- colWidths[j] = Math.max(cell.getPreferredColumnSpan(),
- colWidths[j]);
- }
- row.preferenceChanged(null, true, false);
- }
-
- }
-
- /**
- * Adds a cell to fill in for another cells overflow. The proxy cells
- * are simply for simplification of layout and have no useful semantics.
- */
- void addProxy(int row, int col, TableCell host) {
- TableRow rv = (TableRow) getView(row);
- rv.insert(col, new ProxyCell(host));
- }
-
- /**
- * Performs layout of the children. The size is the
- * area inside of the insets. The table layout is mostly
- * the default behavior of the boxes, where the requests
- * made by the cells for their width is based upon
- * a common set of values held in the table. The table
- * itself calculates these values before the layout
- * proceeds and these values get used by the cells.
- *
- * @param width the width >= 0
- * @param height the height >= 0
- */
- protected void layout(int width, int height) {
- calculateGrid();
- super.layout(width, height);
- }
-
- // ---- View methods ----------------------------------------------------
-
- int[] colWidths;
-
- /**
- * View of a row in a table.
- */
- public class TableRow extends BoxView {
-
- /**
- * Constructs a TableView for the given element.
- *
- * @param elem the element that this view is responsible for
- */
- public TableRow(Element elem) {
- super(elem, View.X_AXIS);
- }
-
- /**
- * Loads all of the children to initialize the view.
- * This is called by the <code>setParent</code> method.
- * This is reimplemented to build cells using the
- * <code>createTableCell</code> method.
- *
- * @param f the view factory
- */
- protected void loadChildren(ViewFactory f) {
- Element e = getElement();
- int n = e.getElementCount();
- if (n > 0) {
- View[] added = new View[n];
- for (int i = 0; i < n; i++) {
- added[i] = createTableCell(e.getElement(i));
- }
- replace(0, 0, added);
- }
- }
-
- }
-
- /**
- * View of a cell in a table
- */
- public class TableCell extends BoxView {
-
- /**
- * Constructs a TableCell for the given element.
- *
- * @param elem the element that this view is responsible for
- */
- public TableCell(Element elem) {
- super(elem, View.Y_AXIS);
- }
-
- /**
- * Gets the number of columns this cell spans (e.g. the
- * grid width).
- *
- * @return the number of columns
- */
- public int getColumnCount() {
- return 1;
- }
-
- /**
- * Gets the number of rows this cell spans (that is, the
- * grid height).
- *
- * @return the number of rows
- */
- public int getRowCount() {
- return 1;
- }
-
- /**
- * Sets the grid location.
- *
- * @param row the row >= 0
- * @param col the column >= 0
- */
- public void setGridLocation(int row, int col) {
- this.row = row;
- this.col = col;
- }
-
- /**
- * Gets the preferred span for the column occupied. This
- * is basically the host's desired column span.
- * The host divides its desired across the number
- * of grid points.
- *
- * @return the span
- */
- public int getPreferredColumnSpan() {
- return ((int) super.getPreferredSpan(X_AXIS)) / getColumnCount();
- }
-
- // --- View methods -----------------------------
-
- /**
- * Renders using the given rendering surface and area on that
- * surface. This is implemented to delegate to the superclass
- * after adjusting the allocation if needed because the
- * cell spans multiple grid points (eg. muliple columns
- * and/or rows).
- *
- * @param g the rendering surface to use
- * @param allocation the allocated region to render into
- * @see View#paint
- */
- public void paint(Graphics g, Shape allocation) {
- Rectangle alloc = allocation.getBounds();
- int nrows = getRowCount();
- int ncols = getColumnCount();
- if (nrows > 1 || ncols > 1) {
- // adjust the allocation
- for (int i = 1; i < ncols; i++) {
- alloc.width += getColumnSpan(col + i);
- }
- for (int i = 1; i < nrows; i++) {
- alloc.height += getRowSpan(row + i);
- }
- }
- }
-
- /**
- * Determines the preferred span for this view along an
- * axis. For the x axis, this is implemented to return
- * the column width for the grid location that this cell
- * lives at. This is the method that is effectively
- * controlling the layout of the table. Cells can be
- * independantly altered by re-implementing this method.
- *
- * @param axis may be either View.X_AXIS or View.Y_AXIS
- * @returns the span the view would like to be rendered into.
- * Typically the view is told to render into the span
- * that is returned, although there is no guarantee.
- * The parent may choose to resize or break the view.
- */
- public float getPreferredSpan(int axis) {
- switch (axis) {
- case View.X_AXIS:
- return getColumnSpan(col);
- default:
- return super.getPreferredSpan(axis);
- }
- }
-
- int row;
- int col;
- }
-
- /**
- * A special table cell that simply occupies space in the
- * table at a grid location to make calculations easier to
- * deal with.
- */
- class ProxyCell extends TableCell {
-
- ProxyCell(TableCell host) {
- super(host.getElement());
- }
-
- /**
- * Loads all of the children to initialize the view.
- * This is called by the <code>setParent</code> method.
- * This is reimplemented to do nothing... proxy cells
- * are just a place holder.
- *
- * @param f the view factory
- */
- protected void loadChildren(ViewFactory f) {
- }
-
- /**
- * Gets the preferred span for the column occupied. This
- * is basically the host's desired column span.
- * The host divides its desired across the number
- * of grid points.
- */
- public int getPreferredColumnSpan() {
- return host.getPreferredColumnSpan();
- }
-
- /**
- * Renders using the given rendering surface and area on that
- * surface. This is implemented to do nothing as proxy cells
- * are supposed to be invisible place holders.
- *
- * @param g the rendering surface to use
- * @param allocation the allocated region to render into
- * @see View#paint
- */
- public void paint(Graphics g, Shape allocation) {
- }
-
- TableCell host;
- }
- }
-